package xcmg.device.service.borrowMaterial;

import com.github.pagehelper.PageInfo;
import yb.ecp.fast.infra.util.PageHelperPlus;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import xcmg.device.dao.entity.borrowMaterial.BorrowMaterialDO;
import xcmg.device.dao.entity.borrowMaterial.BorrowMaterialDetailDO;
import xcmg.device.dao.entity.borrowMaterial.BorrowMaterialExportDO;
import xcmg.device.dao.entity.borrowMaterial.BorrowMaterialMesModel;
import xcmg.device.dao.entity.borrowMaterial.BorrowMaterialPrintVO;
import xcmg.device.dao.mapper.borrowMaterial.BorrowMaterialMapper;
import xcmg.device.infra.ConstantInfo;
import xcmg.device.infra.DateUtil;
import xcmg.device.infra.ErrorCode;
import xcmg.device.infra.ExportUtil;
import xcmg.device.infra.StringUtil;
import xcmg.device.infra.enums.BillDesc;
import xcmg.device.service.GenDocumentService;
import xcmg.device.service.vo.warehouse.WarehouseInboundAddVO;
import xcmg.device.service.vo.warehouse.WarehouseInboundDetailVO;
import xcmg.device.service.vo.warehouse.WarehouseInboundVO;
import xcmg.device.service.warehouse.WarehouseInboundService;
import yb.ecp.fast.feign.FastGenClient;
import yb.ecp.fast.infra.infra.ActionResult;
import yb.ecp.fast.infra.infra.PageCommonVO;
import yb.ecp.fast.infra.infra.SearchCommonVO;

import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author ZHANGK
 * @date 2020/6/11
 **/
@Service
@Slf4j
public class BorrowMaterialService {

    @Autowired
    BorrowMaterialMapper borrowMaterialMapper;

    @Autowired
    FastGenClient fastGenClient;

    @Autowired
    BorrowMaterialDetailService borrowMaterialDetailService;

    @Autowired
    GenDocumentService genDocumentService;

    @Autowired
    private WarehouseInboundService warehouseInboundService;

    @Autowired
    private HttpServletResponse response;


    @Transactional(rollbackFor = Exception.class)
    public ErrorCode insert(BorrowMaterialDO borrowMaterialDO) throws Exception {
        ActionResult<String> guidResult = fastGenClient.textGuid();
        if (guidResult == null || guidResult.getCode() != ErrorCode.Success.getCode()) {
            log.error("主键生成失败！");
            return ErrorCode.Failure;
        }

        String code = genDocumentService.genDocumentNo(BillDesc.BorrowMaterial, borrowMaterialDO.getOrgId());

        borrowMaterialDO.setId(guidResult.getValue());
        borrowMaterialDO.setCode(code);
        borrowMaterialDO.setCreatedDate(new Date());
        borrowMaterialDO.setOneLevelAuditStatus(ConstantInfo.BORROW_ONE_LEVEL_STATUS_WAIT);
        borrowMaterialDO.setTwoLevelAuditStatus(ConstantInfo.BORROW_TWO_LEVEL_STATUS_WAIT);
        borrowMaterialDO.setStatus(ConstantInfo.BORROW_NOT_INBOUND);

        List<WarehouseInboundDetailVO> inDetailList = new ArrayList<>();

        WarehouseInboundAddVO warehouseInboundAddVO = new WarehouseInboundAddVO();

        List<BorrowMaterialDetailDO> detailDOList = borrowMaterialDO.getBorrowMaterialDetailDOList();
        for (BorrowMaterialDetailDO detailDO : detailDOList) {
            guidResult = fastGenClient.textGuid();
            if (guidResult == null || guidResult.getCode() != ErrorCode.Success.getCode()) {
                log.error("主键生成失败！");
                return ErrorCode.Failure;
            }
            detailDO.setId(guidResult.getValue());
            detailDO.setBorrowId(borrowMaterialDO.getId());
            borrowMaterialDetailService.insert(detailDO);

            WarehouseInboundDetailVO detail = new WarehouseInboundDetailVO();
            detail.setBusinessSingle(code.substring(0, 5));
            detail.setBusinessOrder(code);
            detail.setMaterialNo(detailDO.getMaterialNo());
            detail.setMaterialName(detailDO.getMaterialDesc());
            //detail.setMaterialType(detailVO.getMaterialsType());
            //detail.setUnit(detailVO.getUnit());
            detail.setAmount(detailDO.getAmount());
            detail.setRealAmount(BigDecimal.ZERO);
            inDetailList.add(detail);
        }
        borrowMaterialMapper.insert(borrowMaterialDO);
        //borrowMaterialDetailService.batchInsert(borrowMaterialDO.getBorrowMaterialDetailDOList());

        //增加入库记录
        WarehouseInboundVO warehouseInboundVO = new WarehouseInboundVO();
        warehouseInboundVO.setBusinessSingle(code.substring(0, 5));
        warehouseInboundVO.setBusinessOrder(code);
        warehouseInboundVO.setWarehouseCode(borrowMaterialDO.getWarehouseLeadIn());
        warehouseInboundVO.setInArea(borrowMaterialDO.getWarehouseAreaLeadIn());
        BigDecimal num = borrowMaterialDO.getBorrowMaterialDetailDOList().stream().map(BorrowMaterialDetailDO::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
        warehouseInboundVO.setAmount(num);
        warehouseInboundAddVO.setHeaderInfo(warehouseInboundVO);
        warehouseInboundAddVO.setDetailList(inDetailList);
        warehouseInboundService.add(warehouseInboundAddVO, borrowMaterialDO.getCreatedId(), borrowMaterialDO.getOrgId());

        return ErrorCode.Success;
    }

    @Transactional(rollbackFor = Exception.class)
    public ErrorCode deleteById(BorrowMaterialDO borrowMaterialDO,String orgId) {
        borrowMaterialDO = borrowMaterialMapper.selectById(borrowMaterialDO.getId());
        borrowMaterialMapper.delete(borrowMaterialDO);
        BorrowMaterialDetailDO borrowMaterialDetailDO = new BorrowMaterialDetailDO();
        borrowMaterialDetailDO.setBorrowId(borrowMaterialDO.getId());
        borrowMaterialDetailService.delete(borrowMaterialDetailDO);

        List<String> bussinessNos = Lists.newArrayList();
        bussinessNos.add(borrowMaterialDO.getCode());
        warehouseInboundService.removeByBusinessOrders(bussinessNos,orgId);
        return ErrorCode.Success;
    }

    @Transactional(rollbackFor = Exception.class)
    public ErrorCode updateById(BorrowMaterialDO borrowMaterialDO) {
        List<BorrowMaterialDetailDO> detailDOList = borrowMaterialDO.getBorrowMaterialDetailDOList();

        if (ObjectUtils.isEmpty(detailDOList)) {
            borrowMaterialMapper.updateById(borrowMaterialDO);
            return ErrorCode.Success;
        }

        BorrowMaterialDetailDO borrowMaterialDetailDO = new BorrowMaterialDetailDO();
        borrowMaterialDetailDO.setBorrowId(borrowMaterialDO.getId());
        borrowMaterialDetailService.delete(borrowMaterialDetailDO);

        for (BorrowMaterialDetailDO detailDO : detailDOList) {
            ActionResult<String> guidResult = fastGenClient.textGuid();
            if (guidResult == null || guidResult.getCode() != ErrorCode.Success.getCode()) {
                log.error("主键生成失败！");
                return ErrorCode.Failure;
            }
            detailDO.setId(guidResult.getValue());
            detailDO.setBorrowId(borrowMaterialDO.getId());
            borrowMaterialDetailService.insert(detailDO);
            //warehouseInboundService.updateDetailState(borrowMaterialDO.getCode(), detailDO.getMaterialNo(), detailDO.getAmount(), status, borrowMaterialDO.getOrgId());
        }
        borrowMaterialMapper.updateById(borrowMaterialDO);

        //warehouseInboundService.updateState(borrowMaterialDO.getCode(),materialsScheduleDO.getStatus(), borrowMaterialDO.getOrgId());
        //borrowMaterialDetailService.batchInsert(detailDOList);
        return ErrorCode.Success;
    }

    public PageCommonVO<BorrowMaterialDO> selectList(SearchCommonVO<BorrowMaterialDO> searchCommonVO) {
        PageCommonVO<BorrowMaterialDO> pageCommonVO = new PageCommonVO<>();
        PageHelperPlus.startPage(searchCommonVO.getPageNum(), searchCommonVO.getPageSize());
        PageHelperPlus.orderBy("CREATED_DATE DESC");
        List<BorrowMaterialDO> list = borrowMaterialMapper.selectList(searchCommonVO.getFilters());
        pageCommonVO.setPageInfo(new PageInfo<>(list));
        pageCommonVO.setPageInfoList(list);
        return pageCommonVO;
    }

    public BorrowMaterialDO selectById(String id) {
        BorrowMaterialDO borrowMaterialDO = borrowMaterialMapper.selectById(id);
        BorrowMaterialDetailDO detailDO = new BorrowMaterialDetailDO();
        detailDO.setBorrowId(id);
        List<BorrowMaterialDetailDO> materialDetailDOS = borrowMaterialDetailService.selectList(detailDO);
        if (!ObjectUtils.isEmpty(materialDetailDOS)) {
            borrowMaterialDO.setBorrowMaterialDetailDOList(materialDetailDOS);
        }
        return borrowMaterialDO;
    }

    public List<BorrowMaterialDO> selectList(BorrowMaterialDO borrowMaterialDO) {
        return borrowMaterialMapper.selectList(borrowMaterialDO);
    }

    public List<BorrowMaterialDO> selectBatchByIds(List<String> ids) {
        return borrowMaterialMapper.selectBatchByIds(ids);
    }

    public boolean batchUpdate(List<BorrowMaterialDO> borrowMaterialDOList){
        return borrowMaterialMapper.batchUpdate(borrowMaterialDOList);
    }

    public List<BorrowMaterialPrintVO> selectPrintList(List<String> ids){
        List<BorrowMaterialDO> borrowMaterialDOList = Lists.newArrayList();
        List<BorrowMaterialPrintVO> borrowMaterialPrintVOList = Lists.newArrayList();
        for (String id : ids) {
            BorrowMaterialDO borrowMaterialDO = new BorrowMaterialDO();
            borrowMaterialDO.setId(id);
            borrowMaterialDO.setIsPrint("1");
            borrowMaterialDOList.add(borrowMaterialDO);
        }
        //回写是否打印标记
        borrowMaterialMapper.batchUpdate(borrowMaterialDOList);

        borrowMaterialDOList = borrowMaterialMapper.selectBatchByIds(ids);
        for (BorrowMaterialDO borrowMaterialDO : borrowMaterialDOList) {
            BorrowMaterialPrintVO borrowMaterialPrintVO = new BorrowMaterialPrintVO();
            borrowMaterialPrintVO.setHeaderInfo(borrowMaterialDO);
            BorrowMaterialDetailDO borrowMaterialDetailDO = new BorrowMaterialDetailDO();
            borrowMaterialDetailDO.setBorrowId(borrowMaterialDO.getId());
            List<BorrowMaterialDetailDO> borrowMaterialDetailDOList = borrowMaterialDetailService.selectList(borrowMaterialDetailDO);
            //borrowMaterialDO.setBorrowMaterialDetailDOList(borrowMaterialDetailDOList);
            borrowMaterialPrintVO.setMaterialList(borrowMaterialDetailDOList);
            borrowMaterialPrintVOList.add(borrowMaterialPrintVO);
        }
        return borrowMaterialPrintVOList;
    }

    public ErrorCode batchDelete(String[] ids,String orgId){
        List<BorrowMaterialDO> list = borrowMaterialMapper.selectBatchByIds(Arrays.asList(ids));
        //删除入库信息
        if (!ObjectUtils.isEmpty(list)) {
            List<String> businessNos = list.stream().map(BorrowMaterialDO::getCode).collect(Collectors.toList());
            warehouseInboundService.removeByBusinessOrders(businessNos,orgId);
        }
        borrowMaterialMapper.batchDelete(Arrays.asList(ids));
        borrowMaterialDetailService.batchDeleteByBorrowId(Arrays.asList(ids));
        return ErrorCode.Success;
    }

    @Transactional(rollbackFor = Exception.class)
    public boolean updateByCode(BorrowMaterialDO borrowMaterialDO){
        return borrowMaterialMapper.updateByCode(borrowMaterialDO);
    }

    @Transactional(rollbackFor = Exception.class)
    public boolean batchUpdateByCode(List<BorrowMaterialDO> borrowMaterialDOList){
        return borrowMaterialMapper.batchUpdateByCode(borrowMaterialDOList);
    }

    @Transactional(rollbackFor = Exception.class)
    public boolean updateByInbound(String billNo, String materialNo, BigDecimal realAmount,
                                   Integer singelState, Integer totalState, String orgId)throws Exception {
        BorrowMaterialDO param = new BorrowMaterialDO();
        param.setCode(billNo);
        List<BorrowMaterialDO> borrowMaterialDOList = borrowMaterialMapper.selectList(param);
        if (ObjectUtils.isEmpty(borrowMaterialDOList)) {
            return false;
        }
        BorrowMaterialDO inboundDO = borrowMaterialDOList.get(0);
        //BorrowMaterialDetailDO detailDO = borrowMaterialDetailService.findByOrderAndMaterialNo(inboundDO.getId(), materialNo);
        BorrowMaterialDetailDO detailParam = new BorrowMaterialDetailDO();
        detailParam.setMaterialNo(materialNo);
        detailParam.setBorrowId(inboundDO.getId());
        List<BorrowMaterialDetailDO> borrowMaterialDetailDOList = borrowMaterialDetailService.selectList(detailParam);
        if (ObjectUtils.isEmpty(borrowMaterialDetailDOList)) {
            return false;
        }
        BorrowMaterialDetailDO detailDO = borrowMaterialDetailDOList.get(0);
        if (realAmount.compareTo(detailDO.getAmount()) > 0) {
            throw new Exception("实际入库数量不能大于借用量");
        }
//        BigDecimal nowAmount = realAmount;
//        if(detailDO.getRealAmount() != null){
//            nowAmount = realAmount.subtract(detailDO.getRealAmount());
//        }
//        detailDO.setRealAmount(realAmount);
//        detailDO.setStatus(singelState);
//        boolean success = materialsScheduleDetailMapper.update(detailDO)>0;
//        if(success){
        //更新采购入库单记录
        inboundDO.setStatus(totalState);
        inboundDO.setInboundDate(new Date());
        boolean success = borrowMaterialMapper.updateById(inboundDO);
        if (!success) {
            return false;
        }
        //}
        return success;
    }

    @Transactional(rollbackFor = Exception.class)
    public ErrorCode audit(BorrowMaterialDO borrowMaterialDO) throws Exception {
        //一级审核通过，记录一级审核时间
        if (borrowMaterialDO.getOneLevelAuditStatus() != null && "1".equals(borrowMaterialDO.getOneLevelAuditStatus())){
            borrowMaterialDO.setOneLevelAuditDate(new Date());
        }
        boolean result = borrowMaterialMapper.updateById(borrowMaterialDO);
        if (result) {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            BorrowMaterialMesModel borrowMaterialMesModel = new BorrowMaterialMesModel();
            borrowMaterialDO = borrowMaterialMapper.selectById(borrowMaterialDO.getId());
            BorrowMaterialDetailDO borrowMaterialDetailDO = new BorrowMaterialDetailDO();
            borrowMaterialDetailDO.setBorrowId(borrowMaterialDO.getId());
            List<BorrowMaterialDetailDO> materialDetailDOS = borrowMaterialDetailService.selectList(borrowMaterialDetailDO);
            if (ObjectUtils.isEmpty(materialDetailDOS)) {
                throw new Exception("零件明细为空");
            }
            BeanUtils.copyProperties(borrowMaterialDO, borrowMaterialMesModel);
            borrowMaterialMesModel.setExpectedArrivalDate(sdf.format(borrowMaterialDO.getExpectedArrivalDate()));
            sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            borrowMaterialMesModel.setCreatedDate(sdf.format(borrowMaterialDO.getCreatedDate()));
            borrowMaterialMesModel.setMaterialNo(materialDetailDOS.get(0).getMaterialNo());
            borrowMaterialMesModel.setMaterialDesc(materialDetailDOS.get(0).getMaterialDesc());
            borrowMaterialMesModel.setAmount(materialDetailDOS.get(0).getAmount());
            List<BorrowMaterialMesModel> param = Lists.newArrayList();
            param.add(borrowMaterialMesModel);

//            //调用MES接口，抛给MES
//            Map resultMap = mesClient.insertMaterialBorrow(param);
//            String code = resultMap.get("code").toString();
//            if (!code.equals("200")) {
//                String message = resultMap.get("message").toString();
//                throw new Exception("同步mes失败，原因:" + message);
//            }
        }
        return ErrorCode.Success;
    }

    public BorrowMaterialDO selectByCode(String code){
        return borrowMaterialMapper.selectByCode(code);
    }

    public void export(String[] ids) throws Exception {
        BorrowMaterialDO borrowMaterialDO = new BorrowMaterialDO();
        borrowMaterialDO.setIds(Arrays.asList(ids));
        List<BorrowMaterialExportDO> borrowMaterialExportDOList = borrowMaterialMapper.selectExportList(borrowMaterialDO);
        invokeExport(borrowMaterialExportDOList);
    }

    public void exportAll(BorrowMaterialDO condition) throws Exception {
        List<BorrowMaterialExportDO> borrowMaterialExportDOList = borrowMaterialMapper.selectExportList(condition);
        invokeExport(borrowMaterialExportDOList);
    }

    private void invokeExport(List<BorrowMaterialExportDO> doList) throws Exception {
        String title = "借用单数据导出";
        String[] rowsName = new String[]{"序号", "借用单号", "服务信息单号", "吊机编号", "领入仓库",
                "领入库区", "拆借原因", "一级审核状态", "二级审核状态", "入库状态", "备注", "预计归还日期", "出厂编号",
                "借用人", "创建日期", "批次号","一级审核时间","二级审核时间","入库时间","出库时间","实际归还时间",
                "零件编码", "零件名称","数量","明细备注"};
        List<Object[]>  dataList = new ArrayList<Object[]>();
        for (int i = 0; i < doList.size(); i++) {
            BorrowMaterialExportDO exportDO = doList.get(i);
            Object[] objs = new Object[rowsName.length];
            objs[0] = i + 1;
            objs[1] = exportDO.getCode();
            objs[2] = exportDO.getServiceInformationMember();
            objs[3] = exportDO.getCrantNo();
            objs[4] = exportDO.getWarehouseLeadIn();
            objs[5] = exportDO.getWarehouseAreaLeadIn();
            objs[6] = exportDO.getBorrowReasonDesc();
            objs[7] = getAuditStatusDes(exportDO.getOneLevelAuditStatus());
            objs[8] = getAuditStatusDes(exportDO.getTwoLevelAuditStatus());
            objs[9] = getStatusDes(exportDO.getStatus());
            objs[10] = exportDO.getRemarks();
            objs[11] = DateUtil.formatDateTime(exportDO.getExpectedArrivalDate());
            objs[12] = exportDO.getFactoryNumber();
            objs[13] = exportDO.getBorrower();
            objs[14] = DateUtil.formatDateTime(exportDO.getCreatedDate());
            objs[15] = exportDO.getBatchNo();
            objs[16] = DateUtil.formatDateTime(exportDO.getOneLevelAuditDate());
            objs[17] = DateUtil.formatDateTime(exportDO.getTwoLevelAuditDate());
            objs[18] = DateUtil.formatDateTime(exportDO.getInboundDate());
            objs[19] = DateUtil.formatDateTime(exportDO.getDeliveryDate());
            objs[20] = DateUtil.formatDateTime(exportDO.getReturnDate());
            objs[21] = exportDO.getMaterialNo();
            objs[22] = exportDO.getMaterialDesc();
            objs[23] = exportDO.getAmount();
            objs[24] = exportDO.getDetailNote();
            dataList.add(objs);
        }

        ExportUtil exportUtil = new ExportUtil(title, rowsName, dataList);
        exportUtil.export(response);
    }

    private String getAuditStatusDes(String auditStatus) {
        String des = "";
        if (StringUtil.isEmpty(auditStatus)) {
            return des;
        }
        switch (auditStatus) {
            case "0":
                des = "待审核";
                break;
            case "1":
                des = "审核通过";
                break;
            case "2":
                des = "审核拒绝";
                break;
            default:
                des = "";
                break;
        }
        return des;
    }

    private String getStatusDes(Integer status){
        String statusDes = "";
        if (status == null){
            return "";
        }
        switch (status){
            case 0:
                statusDes = "未入库";
                break;
            case 1:
                statusDes = "部分入库";
                break;
            case 2:
                statusDes = "已入库";
                break;
            default:
                statusDes = "";
                break;
        }
        return statusDes;
    }



}
